package com.jovision.demo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.RequiresApi;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.xgakj.mylibrary.mvp.utils.TimeUtil;
import com.example.xgakj.mylibrary.mvp.utils.ToastUtil;
import com.example.xgakj.newterminal.R;
import com.example.xgakj.newterminal.adapter.Play2Adapter;
import com.example.xgakj.newterminal.base.BaseApplication;
import com.example.xgakj.newterminal.base.Parameters;
import com.example.xgakj.newterminal.beans.DeviceBean;
import com.example.xgakj.newterminal.utils.CaptureSreenUtil;
import com.example.xgakj.newterminal.utils.ShotUtils;
import com.jovision.Consts;
import com.jovision.Jni;
import com.jovision.beans.Channel;
import com.jovision.beans.Device;
import com.jovision.tools.AppConsts;
import com.jovision.tools.JVNetConst;
import com.jovision.tools.MyAudio;
import com.jovision.tools.PlayUtil;
import com.socks.library.KLog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

import static java.lang.Math.abs;

public class Play2Activity extends BaseActivity implements OnGestureListener, OnTouchListener, OnClickListener {

    static {
        System.loadLibrary("alu");
        System.loadLibrary("play");
    }

    private static final String TAG = "PlayActivity";
    private static final int DISMISS_DIALOG = 0x01;
    // 视频播放view
    private SurfaceView playSurface;
    private TextView linkState;// 连接状态
    private SurfaceHolder holder;
    private Channel connectChannel;
    private boolean apConnect = false;// 是否Ap直连设备
    private Device device;
    private Button bt_format, iv_hangup, bt_screenshot, bt_record_video;
    private ImageView iv_voice_on, iv_send_audio;
    private PopupWindow mPopupWindow;


    /**** 对讲用 ******/
    public MyAudio playAudio;
    protected RelativeLayout voiceTip;// 单向对讲提示
    protected boolean realStop = false;
    public static boolean AUDIO_SINGLE = false;// 单向对讲标志
    public static boolean VOICECALL_LONG_CLICK = false;// 语音喊话flag长按状态,长按发送数据
    public static boolean VOICECALLING = false;// 对讲功能已经开启
    public static boolean GATHER_AUDIO_DATA = true;// 是否采集音频数据
    public static boolean showingOsd = true;// 是否显示着osd true显示 false没显示

    /**
     * 修改密码输入框
     */
    private int power;
    public String descript = "";
    public int channelIndex;// 连接的通道号
    private Boolean requestIsAlive = false;

    private int video_format = 0;//0标清 1流畅 2高清
    private int[] datas = new int[16];
    private RelativeLayout layout_switch;
    private static final int SWITCH_LAYOUT_CHANGE = 4;
    private boolean isSwitchDirection;
    private String savePath;
    private ShotUtils shotUtils;
    private Disposable mDisposable;
    private CaptureSreenUtil captureSreenUtil;

    public Play2Activity() {
        ttyGestureDetector = new GestureDetector(this);
    }

    /**
     * 视频连接
     *
     * @param device
     * @param channel
     * @param surface
     * @return
     */
    private int connect(Device device, Channel channel, Surface surface) {
        int result = -1;
        if (null != device && null != channel) {
            if ("".equalsIgnoreCase(device.getIp()) || 0 == device.getPort()) {// 无ip和端口走云视通连接
                result = Jni.connect(channel.getIndex(), channel.getChannel(),
                        device.getIp(), device.getPort(), device.getUser(),
                        device.getPwd(), device.getNo(), device.getGid(), true,
                        1, true, JVNetConst.TYPE_3GMOHOME_UDP, surface, false,
                        false, apConnect, false, null);

            } else {// 有Ip用ip连接，云视通号字段需要传-1，否则仍然走的云视通连接
                result = Jni.connect(channel.getIndex(), channel.getChannel(),
                        device.getIp(), device.getPort(), device.getUser(),
                        device.getPwd(), -1, device.getGid(), true, 1, true,
                        JVNetConst.TYPE_3GMOHOME_UDP, surface, false, false,
                        apConnect, false, null);
            }
        }

        return result;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onNotify(int what, int arg1, int arg2, Object obj) {
        handler.sendMessage(handler.obtainMessage(what, arg1, arg2, obj));
        KLog.e("onNotify" + what);
    }

    @Override
    public void onHandler(int what, int arg1, int arg2, Object obj) {
        KLog.e("onHandler" + what);
        dismissDialog();
        switch (what) {
            case Consts.PLAY_FINISH: {

                finish();
                break;
            }
            case DISMISS_DIALOG: {
                linkState.setVisibility(View.GONE);
                break;
            }
            case AppConsts.CALL_NORMAL_DATA: {// O 帧 视频数据回调
                connectChannel.setConnected(true);
                connectChannel.setPaused(false);
                handler.sendEmptyMessage(DISMISS_DIALOG);
                try {
                    JSONObject jobj;
                    jobj = new JSONObject(obj.toString());
                    int type = jobj.optInt("device_type");
                    if (null != jobj) {
                        connectChannel.getParent().setType(type);
                        connectChannel.getParent()
                                .setJFH(jobj.optBoolean("is_jfh"));
                        connectChannel.getParent().set05(jobj.optBoolean("is05"));
                        connectChannel.setAudioType(jobj.getInt("audio_type"));
                        connectChannel.setAudioByte(jobj.getInt("audio_bit"));
                        connectChannel.setAudioEncType(jobj
                                .getInt("audio_enc_type"));
                        connectChannel.setSingleVoice(true);
                        if (8 == connectChannel.getAudioByte()
                                && AppConsts.DEVICE_TYPE_DVR == type) {
                            connectChannel.setSupportVoice(false);
                        } else {
                            connectChannel.setSupportVoice(true);
                        }

                        // 请求文本聊天
                        Jni.sendBytes(arg1, JVNetConst.JVN_REQ_TEXT, new byte[0], 8);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                break;
            }

            case Consts.CALL_NEW_PICTURE: {// I帧
                linkState.setVisibility(View.GONE);
                break;
            }

            case Consts.CALL_TEXT_DATA: {
                Log.i(TAG, "CALL_TEXT_DATA: " + what + ", " + arg1 + ", " + arg2
                        + ", " + obj);

                switch (arg2) {
                    case JVNetConst.JVN_RSP_TEXTACCEPT:// 同意文本聊天
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        // 获取主控码流信息请求
                        Jni.sendTextData(arg1, JVNetConst.JVN_RSP_TEXTDATA, 8,
                                JVNetConst.JVN_STREAM_INFO);

                        // 2015-4-22 获取设备用户名密码
                        Jni.sendSuperBytes(arg1, JVNetConst.JVN_RSP_TEXTDATA, true,
                                Consts.RC_EX_ACCOUNT, Consts.EX_ACCOUNT_REFRESH,
                                Consts.POWER_ADMIN, 0, 0, new byte[0], 0);
                        connectChannel.setAgreeTextData(true);
                        break;
                    case JVNetConst.JVN_CMD_TEXTSTOP:// 不同意文本聊天
                        connectChannel.setAgreeTextData(false);
                        break;

                    case JVNetConst.JVN_RSP_TEXTDATA:// 文本数据
                        String allStr = obj.toString();
                        Log.v(TAG, "文本数据--" + allStr);
                        try {
                            JSONObject dataObj = new JSONObject(allStr);

                            switch (dataObj.getInt("flag")) {
                                // 远程配置请求，获取到配置文本数据
                                case JVNetConst.JVN_GET_USERINFO: {// 20
                                    int extend_type = dataObj.getInt("extend_type");
                                    if (Consts.EX_ACCOUNT_REFRESH == extend_type) {
                                        // CALL_TEXT_DATA: 165, 0, 81,
                                        // {"extend_arg1":64,"extend_arg2":0,"extend_arg3":0,
                                        // "extend_msg":
                                        // "+ID=admin;POWER=4;DESCRIPT=新帐户;+ID=abc;POWER=4;DESCRIPT=新帐户;",
                                        // "extend_type":3,"flag":20,"packet_count":4,"packet_id":0,"packet_length":0,"packet_type":6}

                                        // CALL_TEXT_DATA: 165, 0, 81,
                                        // {"extend_arg1":54,"extend_arg2":0,"extend_arg3":0,"extend_msg":"ID=admin;POWER=4;DESCRIPT=;ID=guest;POWER=1;DESCRIPT=;",
                                        // "extend_type":6,"flag":20,"packet_count":4,
                                        // "packet_id":0,"packet_length":0,"packet_type":6}

                                        String InfoJSON = dataObj.getString("extend_msg");
                                        InfoJSON = InfoJSON.replaceAll("ID", "+ID");
                                        String[] array = InfoJSON.split("\\+");
                                        for (int i = 1; i < array.length; i++) {
                                            if (null != array[i] && !array[i].equals("")) {
                                                HashMap<String, String> idomap = new HashMap<String, String>();
                                                idomap = genMsgMap(array[i]);
                                                int getPower = Integer.parseInt(idomap
                                                        .get("POWER"));
                                                String getDescript = idomap.get("DESCRIPT");
                                                if (idomap.get("ID").equals("admin")
                                                        && 4 == (0x04 & getPower)) {
                                                    Log.e("power-", "" + power);
                                                    power = getPower;
                                                    if (null == getDescript
                                                            || "".equals(getDescript)) {
                                                        descript = "";
                                                    } else {
                                                        descript = getDescript;
                                                    }

                                                }
                                            }
                                        }

                                    } else if (Consts.EX_ACCOUNT_MODIFY == extend_type) {// 修改成功
                                        showTextToast("修改成功");
                                    }
                                    break;
                                }
                                // case JVNetConst.JVN_GET_USERINFO:
                                // showTextToast("设置成功");
                                // break;
                                case JVNetConst.JVN_REQ_CALLBACK: {// 0
                                    // CALL_TEXT_DATA: 165, 0, 81,
                                    // {"extend_arg1":0,"extend_arg2":0,"extend_arg3":9,"extend_type":39,"flag":0,"msg":"abc123456","packet_count":18,"packet_id":0,"packet_length":0,"packet_type":6}
                                    int extendType = dataObj.getInt("extend_type");
                                    if (extendType == Consts.EX_COMTRANS_RESV) {// 透传回调,串口收的回调
                                        String msg = dataObj.getString("msg");
                                        int msgLength = dataObj.getInt("extend_arg3");
                                        Log.v(TAG, "透传回调数据--" + msg + "；透传回调长度--" + msgLength);
                                    } else if (extendType == Consts.EX_START_AP) {// 开启AP请求回调
                                        int nParam1 = dataObj.getInt("extend_arg1");
                                        Log.v(TAG, "nParam1=" + nParam1);
                                        // （2）手机端接受设备端回应，解析pstExt->nParam1的值：
                                        // 若pstExt->nParam1=-1，则不支持wifi；
                                        // 若pstExt->nParam1=1，说明AP模式已经开启；
                                        // 若pstExt->nParam1=0或pstExt->nParam1=2，则可以开启AP。
                                        switch (nParam1) {
                                            case -1:
                                                showTextToast("不支持wifi");
                                                break;
                                            case 1:
                                                showTextToast("AP模式已经开启");
                                                break;
                                            case 0:
                                            case 2:
                                                showTextToast("可以开启AP");
                                                // 发命令开启Ap
                                                Jni.sendSuperBytes(connectChannel.getIndex(),
                                                        JVNetConst.JVN_RSP_TEXTDATA,
                                                        true, Consts.RC_EX_NETWORK,
                                                        Consts.EX_START_AP, 1, 0, 0, null, 0);
                                                handler.sendMessageDelayed(
                                                        handler.obtainMessage(Consts.PLAY_FINISH),
                                                        1000);
                                                break;
                                        }

                                    } else if (extendType == Consts.EX_START_STA) {// 开启STA请求的回调
                                        int nParam1 = dataObj.getInt("extend_arg1");
                                        Log.v(TAG, "nParam1=" + nParam1);
                                        // （2）手机端接受设备端回应，解析pstExt->nParam1的值：
                                        // 若pstExt->nParam1=-1，则不支持wifi；
                                        // 若pstExt->nParam1=0，说明目前尚未配置wifi，无法开启STA（开启了也没用）；
                                        // 若pstExt->nParam1=1，说明STA模式已经开启；
                                        // 若pstExt->nParam1=2，则可以开启STA。
                                        switch (nParam1) {
                                            case -1:
                                                showTextToast("不支持wifi");
                                                break;
                                            case 0:
                                                showTextToast("目前尚未配置wifi，无法开启STA（开启了也没用）");
                                                break;
                                            case 1:
                                                showTextToast("STA模式已经开启");
                                                break;
                                            case 2:
                                                showTextToast("可以开启STA");
                                                // 发命令开启Ap
                                                Jni.sendSuperBytes(connectChannel.getIndex(),
                                                        JVNetConst.JVN_RSP_TEXTDATA,
                                                        true, Consts.RC_EX_NETWORK,
                                                        Consts.EX_START_STA, 1, 0, 0, null, 0);
                                                handler.sendMessageDelayed(
                                                        handler.obtainMessage(Consts.PLAY_FINISH),
                                                        1000);
                                                break;
                                        }

                                    }
                                    break;
                                }
                                case JVNetConst.JVN_REMOTE_SETTING: {// 1--

                                    break;
                                }
                                case JVNetConst.JVN_WIFI_INFO:// 2-- AP,WIFI热点请求
                                    break;
                                case JVNetConst.JVN_STREAM_INFO:// 3-- 码流配置请求
                                    Log.i(TAG, "JVN_STREAM_INFO:TEXT_DATA: " + what + ", "
                                            + arg1 + ", " + arg2 + ", " + obj);
                                    String streamJSON = dataObj.getString("msg");
                                    HashMap<String, String> streamMap = genMsgMap(streamJSON);

                                    if (null != streamMap.get("MobileQuality")
                                            && !"".equalsIgnoreCase(streamMap
                                            .get("MobileQuality"))) {
                                        Log.v(TAG,
                                                "MobileQuality="
                                                        + streamMap.get("MobileQuality"));
                                        int mobileQuality = Integer.parseInt(streamMap
                                                .get("MobileQuality"));

                                    }

                                    if (null != streamMap.get("nPosition")
                                            && "4".equalsIgnoreCase(streamMap
                                            .get("nPosition"))
                                            && null != streamMap.get("nTimePosition")
                                            && "4".equalsIgnoreCase(streamMap
                                            .get("nTimePosition"))) {

                                        showingOsd = false;

                                    } else {

                                    }

                                    Jni.sendString(connectChannel.getIndex(),
                                            JVNetConst.JVN_RSP_TEXTDATA,
                                            true,
                                            Consts.RC_EX_NETWORK, Consts.EX_NW_REFRESH, null);

                                    break;
                                case Consts.EX_NW_REFRESH: {// 8 获取WiFi信息

                                }
                                case JVNetConst.EX_WIFI_AP_CONFIG:// 11
                                    // ---新wifi配置流程
                                    if (0 == dataObj.getInt("result")) {// 配置成功
                                        showTextToast(R.string.set_success);
                                    } else {// 配置失败
                                        showTextToast(R.string.set_failed);
                                    }

                                    break;
                                default:
                                    break;
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        break;
                }
                break;
            }
            case AppConsts.STOP_AUDIO_GATHER: {// 停止采集音频数据
                GATHER_AUDIO_DATA = false;
                break;
            }
            case AppConsts.START_AUDIO_GATHER: {// 开始采集音频数据
                GATHER_AUDIO_DATA = true;
                break;
            }
            case AppConsts.CALL_PLAY_AUDIO: {// 音频数据
                if (!GATHER_AUDIO_DATA) {
                    break;
                }

                if (null != obj && null != playAudio) {
                    if (AUDIO_SINGLE) {// 单向对讲长按才发送语音数据
                        if (VOICECALL_LONG_CLICK) {
                            // 长按时只发送语音，不接收语音
                        } else {
                            byte[] data = (byte[]) obj;
                            // audioQueue.offer(data);
                            // [Neo] 将音频填入缓存队列
                            playAudio.put(data);
                        }
                    } else {// 双向对讲直接播放设备传过来的语音
                        byte[] data = (byte[]) obj;
                        // audioQueue.offer(data);
                        // [Neo] 将音频填入缓存队列
                        playAudio.put(data);
                    }
                }

                break;
            }

            case Consts.CALL_CHAT_DATA: {
                dismissDialog();
                Log.i(TAG, "CALL_CHAT_DATA:arg1=" + arg1 + ",arg2=" + arg2);
                switch (arg2) {
                    // 语音数据
                    case JVNetConst.JVN_RSP_CHATDATA: {
                        Log.i(TAG, "JVN_RSP_CHATDATA");
                        break;
                    }

                    // 同意语音请求
                    case JVNetConst.JVN_RSP_CHATACCEPT: {
                        if (connectChannel.isSingleVoice()) {
                            showTextToast(R.string.voice_tips2);
                        }
                        // recorder.start(channelList.get(lastClickIndex).getAudioType(),
                        // channelList.get(lastClickIndex).getAudioByte());

                        if (AppConsts.JAE_ENCODER_G729 == connectChannel
                                .getAudioEncType()) {
                            // 开启语音对讲
                            playAudio.startPlay(16, true);
                            playAudio.startRec(connectChannel.getIndex(),
                                    connectChannel.getAudioEncType(), 16,
                                    connectChannel.getAudioBlock(), true);
                        } else {
                            // 开启语音对讲
                            playAudio.startPlay(connectChannel.getAudioByte(), true);
                            playAudio.startRec(connectChannel.getIndex(),
                                    connectChannel.getAudioEncType(),
                                    connectChannel.getAudioByte(),
                                    connectChannel.getAudioBlock(), true);

                        }
                        connectChannel.setVoiceCall(true);
                        VOICECALLING = true;

                        break;
                    }

                    // 暂停语音聊天
                    case JVNetConst.JVN_CMD_CHATSTOP: {
                        if (realStop) {
                            realStop = false;
                        } else {
                            showTextToast(R.string.has_calling);
                        }

                        break;
                    }
                    default:
                }
                break;
            }

            case AppConsts.CALL_CONNECT_CHANGE: {// 连接结果
                dismissDialog();
                switch (arg2) {
                    // 1 -- 连接成功
                    case JVNetConst.CONNECT_OK: {
                        connectChannel.setConnected(true);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.GONE);

                        // 视频连接成功，如果连接的用户名密码是默认的建议用户修改管理员密码
                        if (AppConsts.DEFAULT_USER.equalsIgnoreCase(mDeviceBean.getUsr())
                                && AppConsts.DEFAULT_PWD.equalsIgnoreCase(mDeviceBean.getPwd())) {
//                            modifyDialog(R.string.edit_user_pass_tips1);
                        } else {
                            linkState.setVisibility(View.VISIBLE);
                            linkState.setText(R.string.buffering);
                        }

                        // TODO
                        // Jni.enablePlayAudio(connectChannel.getIndex(),
                        // true);//
                        // 指定某个窗口是否要播声音，如果想播声音传true，不播声音传false，如果录像想录声音，一定要传true
                        break;
                    }
                    // 2 -- 断开连接成功
                    case JVNetConst.DISCONNECT_OK: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        JSONObject connectObj;
                        try {
                            connectObj = new JSONObject(obj.toString());
                            String errorMsg = connectObj.getString("msg");
                            linkState.setVisibility(View.VISIBLE);
                            linkState.setText(errorMsg);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        break;
                    }
                    // 4 -- 连接失败
                    case JVNetConst.CONNECT_FAILED: {
                        try {
                            JSONObject connectObj = new JSONObject(obj.toString());
                            String errorMsg = connectObj.getString("msg");
                            if ("password is wrong!".equalsIgnoreCase(errorMsg)
                                    || "pass word is wrong!".equalsIgnoreCase(errorMsg)) {// 密码错误时提示身份验证失败
                                linkState.setText(getResources()
                                        .getString(R.string.connfailed_auth));

                            } else if ("channel is not open!"
                                    .equalsIgnoreCase(errorMsg)) {// 无该通道服务
                                linkState.setText(getResources().getString(
                                        R.string.connfailed_channel_notopen));
                            } else if ("connect type invalid!"
                                    .equalsIgnoreCase(errorMsg)) {// 连接类型无效
                                linkState.setText(getResources().getString(
                                        R.string.connfailed_type_invalid));
                            } else if ("client count limit!".equalsIgnoreCase(errorMsg)) {// 超过主控最大连接限制
                                linkState.setText(getResources().getString(
                                        R.string.connfailed_maxcount));
                            } else if ("connect timeout!".equalsIgnoreCase(errorMsg)) {//
                                linkState.setText(getResources().getString(
                                        R.string.connfailed_timeout));
                            } else if ("check password timeout!"
                                    .equalsIgnoreCase(errorMsg)) {// 验证密码超时
                                linkState.setText(getResources().getString(
                                        R.string.connfailed_checkpass_timout));
                            } else {// "Connect failed!"
                                linkState
                                        .setText(getResources().getString(R.string.connect_failed));
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                            linkState.setText(getResources().getString(R.string.closed));
                        }
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);

                        break;
                    }
                    // 6 -- 连接异常断开
                    case JVNetConst.ABNORMAL_DISCONNECT: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText(getResources().getString(R.string.abnormal_closed1));

                        break;
                    }
                    // 7 -- 服务停止连接，连接断开
                    case JVNetConst.SERVICE_STOP: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText(getResources().getString(R.string.abnormal_closed2));
                        break;
                    }
                    // 3 -- 不必要重复连接
                    case JVNetConst.NO_RECONNECT: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText(getResources().getString(R.string.abnormal_closed3));
                        break;
                    }
                    // 5 -- 没有连接
                    case JVNetConst.NO_CONNECT: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText(getResources().getString(R.string.abnormal_closed4));
                        break;
                    }
                    // 8 -- 断开连接失败
                    case JVNetConst.DISCONNECT_FAILED: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText(getResources().getString(R.string.abnormal_closed5));
                        break;
                    }

                    // 9 -- 其他错误
                    case JVNetConst.OHTER_ERROR: {
                        connectChannel.setConnected(false);
                        connectChannel.setPaused(false);
                        linkState.setVisibility(View.VISIBLE);
                        linkState.setText("其他错误");
                        break;

                    }
                    default:
                }

            }
            default:
        }
    }

    @Override
    protected void initSettings() {
        playAudio = MyAudio.getIntance(AppConsts.PLAY_AUDIO_WHAT,
                Play2Activity.this, 8000);
    }

    @Override
    protected void initUi() {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        init();
        setContentView(R.layout.activity_play2);
        requestIsAlive = true;
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int w = dm.widthPixels;
        int h = dm.heightPixels;
        playSurface = (SurfaceView) findViewById(R.id.playsurface);
        LayoutParams lp = playSurface.getLayoutParams();
        lp.width = w;
        lp.height = h;
        playSurface.setLayoutParams(lp);
        KLog.d("w: " + w + " h: " + h);

        linkState = (TextView) findViewById(R.id.linkstate);
        linkState.setTextColor(Color.GREEN);
        layout_switch = (RelativeLayout) findViewById(R.id.layout_switch);
        bt_format = (Button) findViewById(R.id.bt_format);
        iv_voice_on = (ImageView) findViewById(R.id.iv_voice_on);
        iv_send_audio = (ImageView) findViewById(R.id.iv_send_audio);
        bt_record_video = (Button) findViewById(R.id.bt_record_video);
        bt_screenshot = (Button) findViewById(R.id.bt_screenshot);
        iv_hangup = (Button) findViewById(R.id.iv_hangup);

        bt_format.setOnClickListener(this);
        bt_screenshot.setOnClickListener(this);
        iv_voice_on.setOnClickListener(this);
        iv_send_audio.setOnClickListener(this);
        bt_record_video.setOnClickListener(this);
        iv_hangup.setOnClickListener(this);
        playSurface.setOnTouchListener(this);
        playSurface.setFocusable(true);
        playSurface.setClickable(true);
        playSurface.setLongClickable(true);
        ttyGestureDetector.setIsLongpressEnabled(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            captureSreenUtil = new CaptureSreenUtil();
            captureSreenUtil.createEnvironment(Play2Activity.this);
        }

        holder = playSurface.getHolder();

        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                requestIsAlive = false;
            }

            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void surfaceCreated(SurfaceHolder holder) {

                linkState.setVisibility(View.VISIBLE);
                linkState.setText(R.string.connectting);

                connectChannel = device.getChannelList().get(channelIndex);
                if (!connectChannel.isConnected()) {
                    connectChannel.setParent(device);
                    KLog.e("surfaceCreated");
                    connect(device, connectChannel,
                            holder.getSurface());
                } else if (connectChannel.isConnected()
                        && connectChannel.isPaused()) {
                    boolean result = Jni.sendBytes(connectChannel.getIndex(),
                            JVNetConst.JVN_CMD_VIDEO, new byte[0], 8);
                    connectChannel.setPaused(false);
                    Log.v(TAG, "onResume=" + result);

                    if (result) {
                        boolean resumeRes = Jni.resume(
                                connectChannel.getIndex(), holder.getSurface());
                        Log.v(TAG, "JNI-Play-Resume=" + resumeRes);
                        if (resumeRes) {
                            linkState.setVisibility(View.GONE);
                        }
                    }
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format,
                                       int width, int height) {
            }
        });


        initPopWindowView();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onClick(View v) {
        boolean isLisening = PlayUtil.isPlayAudio(connectChannel.getIndex());
        switch (v.getId()) {
            case R.id.bt_format:
                video_format = video_format + 1;
                if (video_format > 2) {
                    video_format = 0;
                }
                if (video_format == 0)// 标清
                {
                    Jni.sendString(connectChannel.getIndex(), JVNetConst.JVN_RSP_TEXTDATA, false, 0,
                            Consts.TYPE_SET_PARAM, "MobileQuality=2;");
                    bt_format.setText("标清");
                } else if (video_format == 1)// 流畅
                {
                    Jni.sendString(connectChannel.getIndex(), JVNetConst.JVN_RSP_TEXTDATA, false, 0,
                            Consts.TYPE_SET_PARAM, "MobileQuality=3;");
                    bt_format.setText("流畅");
                } else if (video_format == 2)// 高清
                {
                    Jni.sendString(connectChannel.getIndex(), JVNetConst.JVN_RSP_TEXTDATA, false, 0,
                            Consts.TYPE_SET_PARAM, "MobileQuality=1;");
                    bt_format.setText("高清");
                }
                break;
            case R.id.iv_voice_on:// 音频监听
                if (connectChannel.isVoiceCall()) {// 对讲时不允许开监听
                    break;
                }
                if (isLisening) {// 正在监听
                    iv_voice_on.setImageResource(R.drawable.btn_call_sound_out_s);
                    stopAudio(connectChannel.getIndex());
                } else {
                    iv_voice_on.setImageResource(R.drawable.btn_call_sound_out);
                    startAudio(connectChannel.getIndex(),
                            connectChannel.getAudioByte());
                }
                break;
            case R.id.iv_send_audio:
                if (isLisening) {// 正在监听,先停止监听
//                audioListening.setText(R.string.audiolistener);
                    Toast.makeText(Play2Activity.this, R.string.audiolistener, Toast.LENGTH_SHORT).show();
                    stopAudio(connectChannel.getIndex());
                }

                if (AppConsts.JAE_ENCODER_G729 != connectChannel
                        .getAudioEncType()
                        && 8 == connectChannel.getAudioByte()) {
                    showTextToast("不支持此设备");
                    return;
                } else {
                    if (connectChannel.isVoiceCall()) {
//                    voiceCall.setText(R.string.voicecall);
//                	Toast.makeText(Play2Activity.this, R.string.voicecall, Toast.LENGTH_SHORT).show();
//                	iv_send_audio.setBackgroundResource(R.drawable.oval_video);
                        stopVoiceCall(connectChannel.getIndex());
                        connectChannel.setVoiceCall(false);
                        realStop = true;
                        VOICECALLING = false;
                    } else {
                        Play2Activity.AUDIO_SINGLE = connectChannel
                                .isSingleVoice();
                        createDialog("", true);
                        startVoiceCall(connectChannel.getIndex(),
                                connectChannel);
//                    iv_send_audio.setBackgroundResource(R.drawable.oval_video_p);
                    }
                }
                break;
            case R.id.bt_record_video:
                savePath = Parameters.VIDEO_PATH;

                File saveFile = new File(savePath);
                if (!saveFile.exists()) {
                    saveFile.mkdir();
                }

                if (Jni.checkRecord(connectChannel.getIndex())) {// 正在录像
                    Jni.stopRecord();
                    showTextToast(getResources().getString(
                            R.string.record_savedas)
                            + savePath);

                } else {
                    Jni.startRecord(connectChannel.getIndex(), savePath
                            + File.separator + TimeUtil.getCurrDateTime2()
                            + ".mp4", true, true);
                    Toast.makeText(Play2Activity.this, R.string.recording, Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.iv_hangup:
                showPopupWindow();
                break;
            case R.id.bt_screenshot:
                layout_switch.setVisibility(View.INVISIBLE);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    if (captureSreenUtil.startScreenCapture()) {
                        try {
                            Observable.create(new ObservableOnSubscribe<Boolean>() {
                                @Override
                                public void subscribe(@NonNull ObservableEmitter<Boolean> e) throws Exception {
                                    captureSreenUtil.startCapture();
                                    e.onNext(true);
                                    e.onComplete();
                                }
                            })
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Consumer<Boolean>() {
                                        @Override
                                        public void accept(@NonNull Boolean aBoolean) throws Exception {
                                            ToastUtil.showShort(Play2Activity.this, "截图成功");
                                        }
                                    });

                        } catch (Exception e) {
                            ToastUtil.showShort(Play2Activity.this, "截图失败");
                            e.printStackTrace();
                        }
                    }
                }


            default:
                break;
        }

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CaptureSreenUtil.REQUEST_MEDIA_PROJECTION) {
            if (resultCode != Activity.RESULT_OK) {
                Log.d(TAG, "User cancelled");
                Toast.makeText(this, "User cancelled", Toast.LENGTH_SHORT).show();
                return;
            }
            if (this == null) {
                return;
            }
            Log.d(TAG, "Starting screen capture");
            captureSreenUtil.setmResultData(resultCode, data);
            KLog.e("onActivityResult 截图");
            try {
                Observable.create(new ObservableOnSubscribe<Boolean>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<Boolean> e) throws Exception {
                        SystemClock.sleep(1000);
                        KLog.e("subscribe 截图第一次");
                        captureSreenUtil.startCapture();
                        e.onNext(true);
                        e.onComplete();
                    }
                })

                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(@NonNull Boolean aBoolean) throws Exception {
                                ToastUtil.showShort(Play2Activity.this, "截图成功");
                            }
                        });

            } catch (Exception e) {
                ToastUtil.showShort(Play2Activity.this, "截图失败");
                e.printStackTrace();
            }

        }

    }

    private GestureDetector ttyGestureDetector; //云台手势
    private DeviceBean mDeviceBean;

    private void init() {

        mDeviceBean = (DeviceBean) getIntent().getSerializableExtra(Parameters.DEVICE);

        boolean initSdk = Jni.init((getApplication()), 9200,
                Consts.LOG_PATH);

        boolean enableHeler = Jni.enableLinkHelper(true, 3, 10);// 开小助手
        Log.e("enableHeler", enableHeler + "");
        if (initSdk) {
            Jni.enableLog(true);
            String version = Jni.getVersion();
            Log.e("SDK_VERSION", version);
        } else {
            Log.e("initSDK", "initSDK--failed");
        }
        PlayUtil.openBroadCast();
        //获取频道
        int channel = BaseApplication.getFangqu();
        Log.e("shurun", channel + "channel");
        channelIndex = channel == 0 ? 0 : channel - 1;
        Log.e("shurun", channelIndex + "channelIndex");
        String ip = "";
        int port = Integer.parseInt(mDeviceBean.getPort());
        String devFullNo = mDeviceBean.getAddress();
//        String devFullNo = "SC172083836";
        String group = "";
        int yst = -1;
        if (!"".equalsIgnoreCase(devFullNo)) {
            group = PlayUtil.getGroup(devFullNo);
            yst = PlayUtil.getYST(devFullNo);
        }
        String user = mDeviceBean.getUsr();
        String pwd = mDeviceBean.getPwd();
        if (pwd == null) {
            pwd = "";
        }
        int channelCount = 16;
     /*   {\"address\":\"sc172083836\",\"port\":\"9101\"" +
                ",\"usr\":\"admin\",\"pwd\":\"\",\"ifaddr\":2," +
                "\"cust_id\":\"00000001\",\"srvport\":\"3\"}]*/
        device = new Device(ip, port, group, yst, user, pwd, channelCount);
//        需要设置小助手: [{"gid":"SC","no":172150398,"channel":1,"name":"admin","pwd":""}]
//        device=new Device("",9101,"SC",172083836,"admin","",16);
        KLog.d("1: " + ip + " 2: " + port +
                " 3: " + group + " 4: " + yst + " 5: " + user + " 6: " + pwd
                + " 7: " + channelCount);
//         intent.putExtra("APConnect", false);
        PlayUtil.setHelperToDevice(device);

    }


    @Override
    protected void saveSettings() {

    }


    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void freeMe() {
        createDialog("", false);
        if (captureSreenUtil != null) {
            captureSreenUtil.release();
            captureSreenUtil = null;
            KLog.e("captureSreenUtil.release()");
        }
        if (mDisposable != null) {
            mDisposable.dispose();
        }
        if (Jni.checkRecord(connectChannel.getIndex())) {// 正在录像
            Jni.stopRecord();
            showTextToast(getResources().getString(
                    R.string.record_savedas)
                    + savePath);
//		        record.setText(R.string.record);
//		        Toast.makeText(Play2Activity.this, R.string.record, Toast.LENGTH_SHORT).show();
        }
        playAudio.release();
        playAudio = null;
        Jni.disconnect(channelIndex);
        PlayUtil.stopBroadCast();
        Jni.deleteLog();
        Jni.deinit();
        ((BaseApplication) getApplication()).setCurrentNotifyer(null);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onPause() {
        if (null != connectChannel && connectChannel.isConnected()
                && !connectChannel.isPaused()) {
            connectChannel.setPaused(true);
            boolean result = Jni.sendBytes(connectChannel.getIndex(),
                    JVNetConst.JVN_CMD_VIDEOPAUSE, new byte[0], 8);
            Log.v(TAG, "onPause=" + result);
        }
        boolean pauseRes = Jni.pause(connectChannel.getIndex());
        Log.v(TAG, "pauseRes=" + pauseRes);
        if (captureSreenUtil != null) {
            captureSreenUtil.stopScreenCapture();
        }
        super.onPause();
    }

    @Override
    public void onBackPressed() {

        super.onBackPressed();
    }


    /**
     * 开始语音对讲
     */
    public static void startVoiceCall(int index, Channel channel) {
        Jni.sendBytes(index, JVNetConst.JVN_REQ_CHAT, new byte[0], 8);
    }

    /**
     * 停止语音对讲
     */
    public void stopVoiceCall(int index) {
        Jni.sendBytes(index, JVNetConst.JVN_CMD_CHATSTOP, new byte[0], 8);
        // 关闭语音对讲
        playAudio.stopPlay();
        playAudio.stopRec();

    }


    /**
     * 开关对讲线程
     */
    class TalkThread extends Thread {
        private int index = 0;
        private int param = 0;

        TalkThread(int index, int param) {
            this.index = index;
            this.param = param;
        }

        @Override
        public void run() {
            // "talkSwitch=" + tag;// 1开始 0关闭
            for (int i = 0; i < 3; i++) {
                Jni.sendString(index, JVNetConst.JVN_RSP_TEXTDATA, false, 0,
                        AppConsts.TYPE_SET_PARAM,
                        String.format(AppConsts.FORMATTER_TALK_SWITCH, param));
            }
            super.run();
        }

    }


    /**
     * 特定 json 转 HashMap
     *
     * @return
     */
    public HashMap<String, String> genMsgMap(String msg) {
        HashMap<String, String> map = new HashMap<String, String>();

        if (null == msg || "".equalsIgnoreCase(msg)) {
            return null;
        }
        Matcher matcher = Pattern.compile("([^=;]+)=([^=;]+)").matcher(msg);
        while (matcher.find()) {
            map.put(matcher.group(1), matcher.group(2));
        }
        return map;
    }

    /**
     * 应用层开启音频监听功能
     *
     * @param index
     * @return
     */
    public boolean startAudio(int index, int audioByte) {
        boolean open = false;
        if (PlayUtil.isPlayAudio(index)) {// 正在监听,确保不会重复开启
            open = true;
        } else {
            PlayUtil.startAudioMonitor(index);// enable audio
            playAudio.startPlay(audioByte, true);
            open = true;
        }
        return open;
    }

    /**
     * 应用层关闭音频监听功能
     *
     * @param index
     * @return
     */
    public boolean stopAudio(int index) {
        boolean close = false;
        if (PlayUtil.isPlayAudio(index)) {// 正在监听，停止监听
            PlayUtil.stopAudioMonitor(index);// stop audio
            playAudio.stopPlay();
            close = true;
        } else {// 确保不会重复关闭
            close = true;
        }
        return close;
    }


    @Override
    public boolean onDown(MotionEvent e) {
        KLog.d("onDown");
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        KLog.d("onShowPress");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        KLog.d("onSingleTapUp");
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
        isSwitchDirection = true;
        KLog.d("onScroll");
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        KLog.d("onLongPress");
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {
        if (requestIsAlive) {
            KLog.d("onTouch===onFling");
            int cmd = 0;
            float x = e1.getX() - e2.getX();
            float y = e1.getY() - e2.getY();
            if (abs(x) >= abs(y)) {
                if (x < -10) { //左移
                    KLog.d("sendByteDirection===左移");
                    cmd = JVNetConst.JVN_YTCTRL_R;
                } else if (x > 10) { //右移
                    KLog.d("sendByteDirection===右移");
                    cmd = JVNetConst.JVN_YTCTRL_L;
                }
            } else {
                if (y < -10) { //下移
                    KLog.d("sendByteDirection===下移");
                    cmd = JVNetConst.JVN_YTCTRL_D;
                } else if (y > 10) { //上移
                    KLog.d("sendByteDirection===上移");
                    cmd = JVNetConst.JVN_YTCTRL_U;
                }
            }

            if (connectChannel != null && connectChannel.isConnected()) {
                PlayUtil.sendCtrlCMDLongPush(connectChannel.getIndex(), cmd, true);
                Log.d(TAG, "压下");
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (connectChannel != null && connectChannel.isConnected()) {
                PlayUtil.sendCtrlCMDLongPush(connectChannel.getIndex(), cmd, false);
                Log.d(TAG, "放开");
            }
            isSwitchDirection = false;
//            try {
//                Thread.sleep(400);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP && isSwitchDirection == false) {
            KLog.d("onTouch===");
            if (mHandler.hasMessages(SWITCH_LAYOUT_CHANGE)) {
                mHandler.removeMessages(SWITCH_LAYOUT_CHANGE);
            }
            int v2 = layout_switch.getVisibility();
            if (v2 == View.VISIBLE) {
                layout_switch.setVisibility(View.INVISIBLE);
            } else {
                layout_switch.setVisibility(View.VISIBLE);
            }
        }
        return ttyGestureDetector.onTouchEvent(event);
    }

    private void connetVideo(int index) {
        channelIndex = index;
        connectChannel = device.getChannelList().get(channelIndex);
        connectChannel.setParent(device);
        connect(device, connectChannel, holder.getSurface());
        KLog.d("连接 " + channelIndex);
    }

    private void initPopWindowView() {
        for (int i = 0; i < datas.length; i++) {
            datas[i] = i + 1;
        }
        View view = LayoutInflater.from(Play2Activity.this).inflate(R.layout.play2_popupwindow, null);
        ListView mListView = view.findViewById(R.id.listView_account);
        Play2Adapter adapter = new Play2Adapter(Play2Activity.this, datas);
        mListView.setAdapter(adapter);
        mPopupWindow = new PopupWindow(view, 120, 400);
        mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
        mPopupWindow.setOutsideTouchable(true);
        mPopupWindow.setFocusable(true);
        mListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                if (mPopupWindow != null && mPopupWindow.isShowing()) {
                    mPopupWindow.dismiss();
                }
                int i = datas[position] - 1;
                if (channelIndex != i) {
                    new VideoTask().execute(position);
                }
            }
        });
    }

    private class VideoTask extends AsyncTask<Integer, Void, Integer> {

        @Override
        protected Integer doInBackground(Integer... params) {
            KLog.d("断开： " + channelIndex);
            Jni.disconnect(channelIndex);
            handler.sendEmptyMessage(DISMISS_DIALOG);
            return params[0];
        }

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            Message msg = mHandler.obtainMessage();
            msg.what = 1;
            msg.arg1 = datas[result] - 1;
            mHandler.sendMessageDelayed(msg, 1000);
        }

    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    KLog.e("connetVideo");
                    connetVideo(msg.arg1);
                    break;

                default:
                    break;
            }
        }

        ;
    };

    private void showPopupWindow() {
        if (mPopupWindow != null) {
            if (mPopupWindow.isShowing()) {
                mPopupWindow.dismiss();
            } else {
                int[] location = new int[2];
                iv_hangup.getLocationOnScreen(location);
                mPopupWindow.showAtLocation(iv_hangup, Gravity.NO_GRAVITY, location[0], location[1] - mPopupWindow.getHeight());
            }
        }
    }

}
